<?php
/**
 * Created by PhpStorm.
 * User: DELL
 * Date: 2018/11/20
 * Time: 15:48
 */
namespace App\Http\Controllers\Barcode;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Storage\Goods;
use App\Models\Storage\GoodsRecord;
use Illuminate\Support\Facades\Redis;
use App\Models\Base\Product;

class BarcodeController extends Controller
{
    public function __construct()
    {
        $this->middleware('refresh.token');
    }

    public function index(Request $request)
    {
        dd($request->all());
    }

    public function getByNo(Request $request)
    {
        $id = $request->get('id');
        $data = Product::where('NewPRODUCTCD', $id)->with('units')->get()->toArray();
        Redis::del($id);
        if (Redis::exists($id)) {
            $product = json_decode(Redis::get($id));
        } else {
            Redis::set($id, json_encode($data));
            $product = json_decode(Redis::get($id));
        }
        return sendData(200, '', $product);
    }

    public function getBarCode(Request $request)
    {
        $id = $request->get('id');
        $data = DB::table('product')->where('barCode', $id)->get()->toArray();
        Redis::del($id);
        if (Redis::exists($id)) {
            $product = json_decode(Redis::get($id));
        } else {
            Redis::set($id, json_encode($data));
            $product = json_decode(Redis::get($id));
        }
        return sendData(200, '', $product);
    }

    public function stockOut(Request $request)
    {

        $id = $request->all();
        $list = $id;
        if (count($id) == 0) {
            return sendData(402, '内容为空');
        }

        $goods = DB::table('goods as g')
            ->leftJoin('product as p', 'g.product_id', '=', 'p.id')
            ->select('p.NewPRODUCTCD', 'g.available_time', 'g.number')
            ->where('odd', $id[0]['id'])
            ->get()
            ->toArray();
        if (count($goods) == 0) {
            return sendData(402, '没有找到该订单');
        }
        $goods = array_map('get_object_vars', $goods);
        foreach ($id as $k => $v) {
            if (array_key_exists($v['type_code'] . $v['date_code'], $id)) {
                $res = $v['number'] + $id[$v['type_code'] . $v['date_code']]['number'];
                $number = $v['number'] = $res;
                $id[$v['type_code'] . $v['date_code']] = $number;
            }
            $id[$v['type_code'] . $v['date_code']] = $v;
            unset($id[$k]);
        }
        $idSum = [];
        foreach ($id as $ids => $item) {
            $idSum[$ids] = $item['number'];
        }
        foreach ($goods as $key => $val) {
            if (array_key_exists($val['NewPRODUCTCD'] . $val['available_time'], $goods)) {
                $res = $val['number'] + $goods[$val['NewPRODUCTCD'] . $val['available_time']]['number'];
                $goods[$val['NewPRODUCTCD'] . $val['available_time']] = $val['number'] = $res;
            }
            $goods[$val['NewPRODUCTCD'] . $val['available_time']] = $val;
            unset($goods[$key]);
        }
        $goodsSum = [];
        foreach ($goods as $ids => $item) {
            $goodsSum[$ids] = $item['number'];
        }
        $sult = array_diff_assoc($idSum, $goodsSum);
        if (count($sult) == 0) {
            $result = array_diff_assoc($goodsSum, $idSum);
            if (count($result) == 0) {
                try {
                    // 开启事务
                    DB::beginTransaction();
                    $insert = [];
                    foreach ($list as $ke => $va) {
                        $insert[] = [
                            'vbeln' => $va['id'],
                            'number' => $va['number'],
                            'case' => $va['box_code'],
                            'available_time' => $va['date_code'],
                            'NewPRODUCTCD' => $va['type_code'],
                            'created_at' => date('Y-m-d H:i:s')
                        ];
                        $moveCode = DB::table('move_out_dirt')->where('MoveNo', $va['id'])->pluck('id');
                        $adjCode = DB::table('adj_out_dirt')->where('AdjustNo', $va['id'])->pluck('id');
                        $ordCode = DB::table('ord_out_dirt')->where('OrderNo', $va['id'])->pluck('id');
                        DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->update(['status' => '待回传','fh_end' => date('Y-m-d H:i:s')]);
                        DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->update(['status' => '待回传','fh_end' => date('Y-m-d H:i:s')]);
                        DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->update(['status' => '待回传','fh_end' => date('Y-m-d H:i:s')]);
                    }
                    DB::table('binning')->insert($insert);
                    DB::commit();
                } catch (\Exception $e) {
                    DB::rollBack();
                    return $e->getMessage();
                }
                return sendData(200, '复核成功');
            }

            $data = [];
            foreach ($result as $key => $val) {
                $data[] = $key;
            }
            foreach ($data as $item => $re) {
                $da = "新产品代码：" . substr($re, 0, 11) . "效期：" . substr($re, 11, 18) . "的产品没有";
            }
            return sendData(402, $da);
        }
        $data = [];
        foreach ($sult as $key => $val) {
            $data[] = $key;
        }
        foreach ($data as $item => $re) {
            $da = "新产品代码：" . substr($re, 0, 11) . "效期：" . substr($re, 11, 18) . "的产品有误";
        }

        return sendData(402, $da);
    }

    public function getGoods(Request $request)
    {
        $id = $request->get('id');
        $res = $this->checkOrder($id);
        if ($res != 2) {
            return sendData(402, '请选择复核中的订单');
        }
        //创建复核的开始时间
        $moveCode = DB::table('move_out_dirt')->where('MoveNo', $id)->pluck('id');
        $adjCode = DB::table('adj_out_dirt')->where('AdjustNo', $id)->pluck('id');
        $ordCode = DB::table('ord_out_dirt')->where('OrderNo', $id)->pluck('id');
        if (count($moveCode) != 0) {
            $tag = DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->pluck('fh_start');
            if ($tag[0] == null) {
                DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->update(['fh_start' => date('Y-m-d H:i:s')]);
            }
        }
        if (count($adjCode) != 0) {
            $tag = DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->pluck('fh_start');
            if ($tag[0] == null) {
                DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->update(['fh_start' => date('Y-m-d H:i:s')]);
            }
        }
        if (count($ordCode) != 0) {
            $tag = DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->pluck('fh_start');
            if ($tag[0] == null) {
                DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->update(['fh_start' => date('Y-m-d H:i:s')]);
            }
        }
        return sendData(200, '');
    }

    public function checkJanhuoOrder(Request $request)
    {
        $id = $request->get('id');

        $res = $this->checkOrder($id);
        if ($res != 1) {
            return sendData(402, '请选择拣货中的订单');
        }
        //创建拣货的开始时间
        $moveCode = DB::table('move_out_dirt')->where('MoveNo', $id)->pluck('id');
        $adjCode = DB::table('adj_out_dirt')->where('AdjustNo', $id)->pluck('id');
        $ordCode = DB::table('ord_out_dirt')->where('OrderNo', $id)->pluck('id');
        if (count($moveCode) != 0) {
            $tag = DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->pluck('jh_start');
            if ($tag[0] == null) {
                DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->update(['jh_start' => date('Y-m-d H:i:s')]);
            }
        }
        if (count($adjCode) != 0) {
            $tag = DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->pluck('jh_start');
            if ($tag[0] == null) {
                DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->update(['jh_start' => date('Y-m-d H:i:s')]);
            }
        }
        if (count($ordCode) != 0) {
            $tag = DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->pluck('jh_start');
            if ($tag[0] == null) {
                DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->update(['jh_start' => date('Y-m-d H:i:s')]);
            }
        }
        return sendData(200, '');
    }

    private function checkOrder(string $id): int
    {
        $goodsId = DB::table('goods')->where('odd', $id)->get();
        if (count($goodsId) == 0) {
            return 0;
        }
        $moveCode = DB::table('move_out_dirt')->where('MoveNo', $id)->pluck('id');
        $adjCode = DB::table('adj_out_dirt')->where('AdjustNo', $id)->pluck('id');
        $ordCode = DB::table('ord_out_dirt')->where('OrderNo', $id)->pluck('id');
        $move = DB::table('move_out_dirt_tag')->whereIn('related_id', $moveCode)->pluck('status');
        $adj = DB::table('adj_out_dirt_tag')->whereIn('related_id', $adjCode)->pluck('status');
        $ord = DB::table('ord_out_dirt_tag')->whereIn('related_id', $ordCode)->pluck('status');

        if (count($move) != 0) {
            if ($move[0] == '拣货中') {
                return 1;
            }

            if ($move[0] == '复核中') {
                return 2;
            }
        }
        if (count($adj) != 0) {
            if ($adj[0] == '拣货中') {
                return 1;
            }

            if ($adj[0] == '复核中') {
                return 2;
            }
        }
        if (count($ord) != 0) {
            if ($ord[0] == '拣货中') {
                return 1;
            }

            if ($ord[0] == '复核中') {
                return 2;
            }
        }

        return 0;
    }

    public function getJianhuoStockList(Request $request)
    {
        $id = $request->get('id');
        $records = GoodsRecord::where(['odd' => $id, 'stock_no' => '复核区'])->whereIn('type', ['ord_out_dirt', 'move_out_dirt', 'adj_out_dirt'])->orderBy('origin_stock_no', 'asc')->get();
        if (count($records) == 0) return sendData(402, '拣货单错误，请刷新页面');
        $list = [];
        foreach ($records as $record) {
            if (!isset($list[$record->origin_stock_no]) || !$list[$record->origin_stock_no]) {
                $list[$record->origin_stock_no] = ['stock_no' => $record->origin_stock_no, 'status' => 0];
            }
        }

        //从redis获取已经扫描的库位,变更状态
        $stockData = json_decode(Redis::get('jianhuo::' . $id));
        if ($stockData) {
            foreach ($stockData as $stock_no => $data) {
                $list[$stock_no]['status'] = $data->status;
            }
        }
        return sendData(200, '', $list);
    }


    public function getJianhuoStock(Request $request)
    {
        $id = $request->get('id');
        $stock_no = $request->get('stock_no');
        if (!$id || !$stock_no) return sendData(402, '信息错误');

        $records = [];
        // 从redis获取数据
        $stockData = json_decode(Redis::get('jianhuo::' . $id));
        if ($stockData) {
            foreach ($stockData as $key => $data) {
                if ($stock_no == $key) {
                    $records = $data->data;
                    foreach ($records as $item) {
                        $item->product = Product::find($item->product_id);
                    }
                }
            }
            Redis::set('jianhuo::' . $id, json_encode($stockData));
        }
        if (!$records) {
            $records = GoodsRecord::where(['odd' => $id, 'stock_no' => '复核区', 'origin_stock_no' => $stock_no])
                ->whereIn('type', ['ord_out_dirt', 'move_out_dirt', 'adj_out_dirt'])
                ->with('product')
                ->get();
            foreach ($records as $record) {
                $record->scanNumber = 0;
            }
        }

        return sendData(200, '', $records);
    }

    public function doJianhuoStock(Request $request)
    {
        $records = $request->all();
        // 查看是否扫描完成
        $start = $count = 0;
        foreach ($records as $item) {
            if ($item['scanNumber'] > 0) $start = 1;
            if ($item['scanNumber'] == $item['number']) $count++;
        }


        $data = [
            'status' => $count == count($records) ? 2 : ($start == 0 ? 0 : 1),
            'data' => $records
        ];

        $stockData = json_decode(Redis::get('jianhuo::' . $records[0]['odd']));
        $stock_no = $records[0]['origin_stock_no'];
        if (!$stockData) {
            $stockData = new \stdClass();
        }
        $stockData->$stock_no = $data;

        Redis::set('jianhuo::' . $records[0]['odd'], json_encode($stockData));

        return sendData();
    }

    public function doJianhuo(Request $request)
    {
        $id = $request->get('id');
        try {
            DB::beginTransaction();
            if (!$id) {
                return sendData(402, '单号不能为空');
            }
            if (!$stockData = json_decode(Redis::get('jianhuo::' . $id))) {
                return sendData(402, '该单未开始拣货！');
            }

            $records = GoodsRecord::where(['odd' => $id, 'stock_no' => '复核区'])->whereIn('type', ['ord_out_dirt', 'move_out_dirt', 'adj_out_dirt'])->get();
            if (count($records) == 0) return sendData(402, '拣货单错误，请刷新页面');
            $type = '';
            $relatedIds = [];
            foreach ($records as $item) {
                $type = $item->type;
                $relatedIds[] = $item->related_id;
                $stock_no = $item->origin_stock_no;
                if (!isset($stockData->$stock_no) || $stockData->$stock_no->status != 2) {
                    return sendData(402, '未拣货完成，请先完成拣货');
                }
            }
            $res = DB::table($type . '_tag')->whereIn('related_id', $relatedIds)->update(['status' => '复核中','jh_end'=>date('Y-m-d H:i:s')]);
            DB::table('ganher')->where('vbeln', $id)->update(['status' => 'App']);
            if (!$res) return sendData(402, '拣货失败');
            Redis::set('jianhuo::' . $id, null);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return sendData(402, $e->getMessage());
        }
        return sendData();
    }
}
